package com.lin.cloud.disk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lin.cloud.disk.common.annotation.CompanyStatusAnnotation;
import com.lin.cloud.disk.common.constant.RedisConstant;
import com.lin.cloud.disk.common.enums.ECompanyEvent;
import com.lin.cloud.disk.common.enums.ECompanyStatus;
import com.lin.cloud.disk.common.enums.EDeleteStatus;
import com.lin.cloud.disk.common.exception.BusinessException;
import com.lin.cloud.disk.document.CompanyStatusDocument;
import com.lin.cloud.disk.entity.dto.LogicDeleteStatusDTO;
import com.lin.cloud.disk.entity.pojo.Company;
import com.lin.cloud.disk.entity.request.*;
import com.lin.cloud.disk.entity.request.company.*;
import com.lin.cloud.disk.mapper.CompanyMapper;
import com.lin.cloud.disk.service.ICompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * (Company)表服务实现类
 *
 * @author ljc
 * @since 2020-12-29 16:01:31
 */
@Service
@Slf4j
public class CompanyServiceImpl implements ICompanyService {

    @Resource
    private CompanyMapper companyMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 获取公司主体
     * @param companyId
     * @return
     */
    @Override
    public Company getAvailableCompanyById(Long companyId) {
        return companyMapper.getAvailableCompanyById(companyId,new Date());
    }

    /**
     * 修改公司主体信息
     * @param request
     */
    @Override
    public void modifyCompanyInfo(ModifyCompanyInfoRequest request){
        Long companyId = request.getCompanyId() != null? request.getCompanyId() : request.getUserDTO().getCompanyId();
        companyMapper.selectById(companyId);
        // 获取公司主体信息
        Company company = null;
        if (null == request.getBeginTime() && null == request.getEndTime()){
            company = companyMapper.getAvailableCompanyById(companyId,new Date());
        }else{
            // 超级用户
            company = companyMapper.selectById(companyId);
        }
        if (null == company){
            throw new BusinessException("公司主体不存在或已过期");
        }
        BeanUtil.copyProperties(request,company,false);
        company.setUpdateBy(request.getUserDTO().getUsername());
        company.setUpdateTime(new Date());
        int updateCount = companyMapper.updateById(company);
        if (0 != updateCount){
            // 更新成功 重新更新主体信息
            // 计算剩余时间 过期时间 - 当前时间
            if (null == company.getEndTime()){
                company = companyMapper.selectById(companyId);
            }
            Long expireTime = (company.getEndTime().getTime() - System.currentTimeMillis()) / 1000;
            if (expireTime < 0 ){
                throw new BusinessException("有效期小于当前时间选");
            }
            stringRedisTemplate.opsForValue().set(RedisConstant.AVAILABLE_COMPANY + companyId, JSONUtil.toJsonStr(company), expireTime, TimeUnit.MILLISECONDS);
        }else{
            throw new BusinessException("更新公司主体失败,请检查是否过期了");
        }
    }

    /**
     * 添加公司主体信息
     * @param request
     * @return
     */
    @Override
    @CompanyStatusAnnotation(event = ECompanyEvent.INSERT)
    public Long addCompanyInfo(AddCompanyInfoRequest request) {
        Company company = new Company();
        BeanUtil.copyProperties(request,company,false);
        // 设置创建时间
        company.setCreateTime(new Date());
        // 设置创建人
        company.setCreateBy(request.getCreateBy());
        // 设置用户ID
        long companyId = IdWorker.getId();
        company.setId(companyId);
        // 设置默认审核状态
        company.setStatus(ECompanyStatus.WAIT_REVIEW.getStatus());
        // 设置是否删除
        company.setIsDelete(0);
        // 设置云盘开始结束时间 默认是现在
        Date nowTime = new Date();
        company.setBeginTime(nowTime);
        company.setEndTime(nowTime);
        if (StringUtils.isBlank(request.getCreateBy())){
            company.setCreateBy(request.getLegalPerson());
        }
        companyMapper.insert(company);
        return companyId;
    }

    /**
     * 删除公司主体信息
     * @param request
     */
    @Override
    @CompanyStatusAnnotation(event = ECompanyEvent.REMOVE)
    public void deleteCompany(DeleteCompanyRequest request){
        // 获取删除状态实例对象
        LogicDeleteStatusDTO deleteStatusDTO = LogicDeleteStatusDTO.getDeleteStatusInstance(request.getCompanyIdList(),request.getUserDTO().getUsername());
        Integer updateCount = companyMapper.logicDeleteOrRecover(deleteStatusDTO);
        if (0 != updateCount){
            // 逻辑删除成功
            // 更新Redis数据
            stringRedisTemplate.executePipelined(new SessionCallback<Object>() {
                @Override
                public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
                    request.getCompanyIdList().forEach(id->{
                        stringRedisTemplate.delete(RedisConstant.AVAILABLE_COMPANY + id);
                    });
                    return null;
                }
            });
        }else{
            throw new BusinessException("删除公司主体失败,请公司是否存在");
        }
    }


    /**
     * 获取公司主体分页列表
     * @param request
     */
    @Override
    public PageInfo<Company> getCompanyPageList(GetCompanyPageListRequest request){
        // 开启分页
        PageHelper.startPage(request.getPageNum(),request.getPageSize());
        // 查询公司主体数据列表
        List<Company> companyList = companyMapper.getCompanyList(request);
        // 返回分页数据
        PageInfo<Company> pageInfo = new PageInfo<Company>(companyList);
        return pageInfo;
    }

    /**
     * 找回公司主体信息
     * @param request
     */
    @Override
    public void retrieveCompany(RetrieveCompanyRequest request){
        // 获取未删除状态实例对象
        LogicDeleteStatusDTO deleteStatusDTO = LogicDeleteStatusDTO.getUnDeleteStatusInstance(request.getCompanyIdList(),request.getUserDTO().getUsername());
        Integer updateCount = companyMapper.logicDeleteOrRecover(deleteStatusDTO);
        if (0 == updateCount){
            throw new BusinessException("恢复公司主体失败,请公司是否存在");
        }
        return;
    }

    /**
     * 修改公司状态
     * @param companyStatus
     */
    @Override
    @Async
    public void updateCompanyStatus(CompanyStatusDocument companyStatus){
        Company company = new Company();
        company.setId(companyStatus.getCompanyId());
        if (ECompanyStatus.DELETE.getStatus().equals(companyStatus.getStatus())){
            company.setIsDelete(EDeleteStatus.DELETE.getStatus());
        }
        company.setStatus(companyStatus.getStatus());
        company.setUpdateBy(companyStatus.getCreateBy());
        company.setUpdateTime(companyStatus.getCreateTime());
        companyMapper.updateById(company);
    }

    /**
     * 审核公司状态
     * @param reviewCompanyStatusRequest
     */
    @Override
    @CompanyStatusAnnotation(event = ECompanyEvent.UPDATE)
    public void reviewCompanyStatus(ReviewCompanyStatusRequest reviewCompanyStatusRequest){
        Company company = new Company();
        company.setId(reviewCompanyStatusRequest.getCompanyId());
        company.setStatus(reviewCompanyStatusRequest.getStatus());
        company.setUpdateBy(reviewCompanyStatusRequest.getUserDTO().getUsername());
        company.setUpdateTime(new Date());
        int updateCount = companyMapper.updateById(company);
        if (0 == updateCount){
            throw new BusinessException("审核失败, 请检查参数是否正确");
        }
    }

    /**
     * 通过ID查询
     * @param id
     * @return
     */
    @Override
    public Company findById(Long id){
        return companyMapper.selectById(id);
    }

    /**
     * 获取可用的公司
     * @return
     */
    @Override
    public List<Company> getAvailableCompany(){
        List<Company> companyList = companyMapper.getAvailableCompany();
        if (CollectionUtil.isEmpty(companyList)){
            return Collections.EMPTY_LIST;
        }
        return companyList;
    }

    /**
     * 根据ID更新
     * @param company
     */
    @Override
    public Integer updateById(Company company){
        return companyMapper.updateById(company);
    }

    /**
     * 获取过期的公司列表
     * @return
     */
    @Override
    public List<Long> getExpireCompanyList() {
        List<Long> companyIdList = companyMapper.getExpireCompanyList(new Date());
        if (CollectionUtil.isEmpty(companyIdList)){
            return Collections.EMPTY_LIST;
        }
        return companyIdList;
    }

    /**
     * 设置为已过期
     * @param expireCompanyList
     */
    @Override
    public void setCompanyStatusExpire(List<Long> expireCompanyList) {
        if (CollectionUtil.isEmpty(expireCompanyList)){
            return ;
        }
        companyMapper.setCompanyStatusExpire(expireCompanyList);
    }
}